Fraction to Recurring Decimal

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

If the fractional part is repeating, enclose the repeating part in parentheses.

For example,

  • Given numerator = 1, denominator = 2, return “0.5”.
  • Given numerator = 2, denominator = 1, return “2”.
  • Given numerator = 2, denominator = 3, return “0.(6)”.

Hint:

  1. No scary math, just apply elementary math knowledge. Still remember how to perform a long division?
  2. Try a long division on 4/9, the repeating part is obvious. Now try 4/333. Do you see a pattern?
  3. Be wary of edge cases! List out as many test cases as you can think of and test your code thoroughly.

Solution:

  1. public class Solution {
  2. public String fractionToDecimal(int numerator, int denominator) {
  3. // zero denominator
  4. if (denominator == 0) return "NaN";
  5. // zero numerator
  6. if (numerator == 0) return "0";
  7. StringBuilder res = new StringBuilder();
  8. Long n = new Long(numerator);
  9. Long d = new Long(denominator);
  10. // determine the sign
  11. if (n < 0 ^ d < 0) res.append('-');
  12. // remove sign of operands
  13. n = Math.abs(n); d = Math.abs(d);
  14. // append integral part
  15. res.append(Long.toString(n / d));
  16. // in case no fractional part
  17. if (n % d == 0) return res.toString();
  18. res.append('.');
  19. Map<Long, Integer> map = new HashMap<Long, Integer>();
  20. // simulate the division process
  21. for (Long r = n % d; r > 0; r %= d) {
  22. // meet a known remainder
  23. // so we reach the end of the repeating part
  24. if (map.containsKey(r)) {
  25. res.insert(map.get(r), "(");
  26. res.append(")");
  27. break;
  28. }
  29. // the remainder is first seen
  30. // remember the current position for it
  31. map.put(r, res.length());
  32. r *= 10;
  33. // append the quotient digit
  34. res.append(Long.toString(r / d));
  35. }
  36. return res.toString();
  37. }
  38. }